﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using VASJ.Model;



namespace VASJ.Service.Library.Manager
{
    public class ProjectManager : BaseManager
    {
        /// <summary>
        /// Init
        /// </summary>
        /// <param name="_ApplicationName"></param>
        public ProjectManager(string _ApplicationName)
            : base(_ApplicationName)
        {

        }

        #region  "Private Function"
        /// <summary>
        /// Author: Hoang Van Tai
        /// Get new Main projet 
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        private int _GetNewMainPrjByName(string name)
        {
            try
            {
                var mainPrj = (int)(from p in this.mdb.AHSMainProjects where p.Name == name select p.Id).FirstOrDefault();

                if (mainPrj != 0)
                {
                    return mainPrj;
                }

                return 0;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager._GetNewMainPrjByName {0}", ex);
                
                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get MainProject for name
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        private AHSMainProject _GetMainProjectByName(string name)
        {
            try
            {
                var mainPrj = from mp in this.mdb.AHSMainProjects
                              where mp.Name == name
                              select mp;
                if (mainPrj.Any())
                {
                    return mainPrj.FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager._GetMainProjectByName {0}", ex);
                
            }
            return null;
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Remove the list user into the project
        /// </summary>
        /// <param name="mainPrjId"></param>
        /// <param name="idUserRoles"></param>
        /// <returns></returns>
        private int _RemoveUsersToProject(int mainPrjId, string[] idUserRoles)
        {
            try
            {
                string idUsers;

                // If idUserRoles is null then remove users for Projectid  
                if (idUserRoles == null || idUserRoles.Any() == false)
                {
                    var deletedAlls = from uip in this.mdb.AHSUserInProjects
                                      where (uip.Projectid == mainPrjId) && 
                                            (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                      select uip;

                    if (deletedAlls != null)
                    {
                        this.mdb.AHSUserInProjects.DeleteAllOnSubmit(deletedAlls);
                    }
                }
                else
                {
                    idUsers = "";

                    foreach (var idUserRole in idUserRoles)
                    {
                        // Format idUser^idRole
                        string[] arrUserRole = idUserRole.Split('^');

                        idUsers += arrUserRole[0];
                        idUsers += ",";
                    }

                    if (idUsers.Trim() != "")
                    {
                        string idUser = idUsers.Substring(0, idUsers.Length - 1);
                        var arrIdUserDels = idUser.Split(',').Select(x => Guid.Parse(x));

                        if (arrIdUserDels.Any())
                        {
                            var deleteds = from uip in this.mdb.AHSUserInProjects
                                           where (uip.Projectid == mainPrjId) && (arrIdUserDels.Contains(uip.Userid) == false) &&
                                                 (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                           select uip;

                            if (deleteds != null)
                            {
                                this.mdb.AHSUserInProjects.DeleteAllOnSubmit(deleteds);
                            }
                        }
                    }
                }

                this.mdb.SubmitChanges();

                return 0;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager._RemoveUsersToProject error {0}", ex);

                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Remove the organization into the project
        /// </summary>
        /// <param name="mainPrjId"></param>
        /// <param name="idOrgRoles"></param>
        /// <returns></returns>
        private int _RemoveOrgsToProject(int mainPrjId, string[] idOrgRoles)
        {
            try
            {
                string idOrgs;

                if (idOrgRoles == null)
                {
                    var deletedAlls = from org in this.mdb.AHSOrganizationInProjects
                                      where (org.Projectid == mainPrjId) && 
                                            (org.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                      select org;

                    if (deletedAlls != null)
                    {
                        this.mdb.AHSOrganizationInProjects.DeleteAllOnSubmit(deletedAlls);
                    }
                }
                else
                {
                    idOrgs = "";

                    foreach (var idOrgRole in idOrgRoles)
                    {
                        // Format idOrg^idRole
                        string[] arrOrgRole = idOrgRole.Split('^');

                        idOrgs += arrOrgRole[0];
                        idOrgs += ",";
                    }

                    if (idOrgs.Trim() != "")
                    {
                        string idOrg = idOrgs.Substring(0, idOrgs.Length - 1);
                        var arrIdOrgDels = idOrg.Split(',').Select(x => Guid.Parse(x));

                        if (arrIdOrgDels.Any())
                        {
                            var deleteds = from org in this.mdb.AHSOrganizationInProjects
                                           where (org.Projectid == mainPrjId) && (arrIdOrgDels.Contains(org.Orgid) == false) &&
                                                (org.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                           select org;

                            if (deleteds != null)
                            {
                                this.mdb.AHSOrganizationInProjects.DeleteAllOnSubmit(deleteds);
                            }
                        }
                    }
                }

                this.mdb.SubmitChanges();

                return 0;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager_RemoveOrgsToProject error {0}", ex);

                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Update the organization into the project for mainPrjId
        /// </summary>
        /// <param name="OrgID"></param>
        /// <param name="idPrjRoles"></param>
        /// <returns></returns>
        private int _UpdateOrgsToProject(int mainPrjId, string[] idOrgRoles)
        {
            try
            {
                foreach (var idOrgRole in idOrgRoles)
                {
                    // Format idUser^idRole
                    string[] arrOrgRole = idOrgRole.Split('^');
                    var orgs = (from org in this.mdb.AHSOrganizationInProjects
                                where (org.Orgid == Guid.Parse(arrOrgRole[0]) && (org.Projectid == mainPrjId)) && 
                                      (org.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                select org).FirstOrDefault();

                    if (orgs != null)
                    {
                        if ((arrOrgRole[1] == null) || (arrOrgRole[1].ToString() == "00000000-0000-0000-0000-000000000000"))
                        {
                            orgs.Roleid = null;
                        }
                        else
                        {
                            orgs.Roleid = Guid.Parse(arrOrgRole[1]);
                        }
                    }
                    else
                    {
                        // Add new item Org  in to Project
                        AHSOrganizationInProject orgInProject = new AHSOrganizationInProject();

                        orgInProject.Orgid = Guid.Parse(arrOrgRole[0]);
                        orgInProject.Projectid = mainPrjId;

                        if ((arrOrgRole[1] == null) || (arrOrgRole[1].ToString() == "00000000-0000-0000-0000-000000000000"))
                        {
                            orgInProject.Roleid = null;
                        }
                        else
                        {
                            orgInProject.Roleid = Guid.Parse(arrOrgRole[1]);
                        }

                        orgInProject.IsInvite = false;
                        orgInProject.Status = 1;

                        this.mdb.AHSOrganizationInProjects.InsertOnSubmit(orgInProject);
                    }
                }

                this.mdb.SubmitChanges();

                return 1;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager._UpdateOrgsToProject error {0}", ex);

                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Update list user and role of the user into project for mainPrjId
        /// </summary>
        /// <param name="mainPrjId"></param>
        /// <param name="idUserRoles"></param>
        /// <returns></returns>
        private int _UpdateUsersToProject(int mainPrjId, string[] idUserRoles)
        {
            try
            {
                foreach (var idUserRole in idUserRoles)
                {
                    // Format idUser^idRole
                    string[] arrUserRole = idUserRole.Split('^');

                    var uips = (from uip in this.mdb.AHSUserInProjects
                                where (uip.Userid == Guid.Parse(arrUserRole[0]) && (uip.Projectid == mainPrjId)) && 
                                      (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                select uip).FirstOrDefault();

                    if (uips != null)
                    {
                        if ((arrUserRole[1] == null) || (arrUserRole[1].ToString() == "00000000-0000-0000-0000-000000000000"))
                        {
                            uips.Roleid = null;
                        }
                        else
                        {
                            uips.Roleid = Guid.Parse(arrUserRole[1]);
                        }
                    }
                    else
                    {
                        // Add new item User in to Project
                        AHSDbContext.AHSUserInProject userInProject = new AHSDbContext.AHSUserInProject();

                        userInProject.Userid = Guid.Parse(arrUserRole[0]);
                        userInProject.Projectid = mainPrjId;

                        if ((arrUserRole[1] == null) || (arrUserRole[1].ToString() == "00000000-0000-0000-0000-000000000000"))
                        {
                            userInProject.Roleid = null;
                        }
                        else
                        {
                            userInProject.Roleid = Guid.Parse(arrUserRole[1]);
                        }

                        userInProject.Status = 1;
                        userInProject.IsInvite = false;

                        this.mdb.AHSUserInProjects.InsertOnSubmit(userInProject);
                    }
                }

                this.mdb.SubmitChanges();

                return 1;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager._UpdateUsersToProject error {0}", ex);

                return -1;
            }
        }

        /// <summary>
        /// Author:Hoang Van Tai
        /// // Get Project 
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public Project GetProject(int projectId)
        {
            Project ret = null ;

            try
            {
                var prj = (from prjs in this.mdb.AHSMainProjects
                           join uip in this.mdb.AHSUserInProjects on prjs.Id equals uip.Projectid
                           where ((prjs.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (prjs.Id == projectId))
                           select new { project = prjs, userid = uip.Userid, rolenameforuserinproject = (uip.Roleid != null ? uip.AHSAspnetRole.Roledisplay : "not set role"), roleidforuserinproject = (uip.Roleid.HasValue ? uip.Roleid.Value : Guid.Empty) }).FirstOrDefault();

                if (prj != null)
                {
                    ret = new Project();

                    ret.Id = prj.project.Id;
                    ret.Name = prj.project.Name;
                    ret.Description = prj.project.Description;
                    ret.DateCreated = prj.project.DateCreated;
                    ret.EndDate = prj.project.EndDate;
                    ret.Owner = prj.project.Owner;
                    ret.OwnerIsUser = (prj.project.OwnerIsUser != null && prj.project.OwnerIsUser.Value);

                    if (prj.project.OwnerID != null)
                    {
                        ret.OwnerId = prj.project.OwnerID.Value;
                        ret.OwnerName = prj.project.AHSAspnetMembership.AHSAspnetUser.Username;
                    }

                    if (prj.project.OrgOwnerID != null)
                    {
                        ret.OrgOwnerId = prj.project.OrgOwnerID.Value;
                        ret.OwnerName = prj.project.AHSOrganization.Name;
                    }

                    ret.ProjectTypeId = prj.project.ProjectTypeID.HasValue ? prj.project.ProjectTypeID : 0;
                    ret.ProjectTypeName = prj.project.ProjectTypeID.HasValue ? prj.project.AHSProjectType.Name : string.Empty;
                    ret.isPM = prj.project.AHSProjectType.IsPM.HasValue ? prj.project.AHSProjectType.IsPM.Value : false;
                    ret.RoleTypeId = (prj.project.RoleTypeID != null) ? prj.project.RoleTypeID : 0;

                    if (!string.IsNullOrEmpty(prj.project.AHSProjectType.PathIcon)) ret.ProjectTypeIcon = prj.project.AHSProjectType.PathIcon;

                    if (!string.IsNullOrEmpty(prj.project.AHSProjectType.ApplicationURL)) ret.ApplicationURL = prj.project.AHSProjectType.ApplicationURL;

                    ret.RoleNameForUserInProject = prj.rolenameforuserinproject;
                    ret.RoleIDForUserInProject = prj.roleidforuserinproject;
                }

                return ret;

            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetProject error {0}", ex);
            }

            return ret;
        }


        /// <summary>
        /// Author: Hoang Van Tai
        /// Get the project type for ApplicationName
        /// </summary>
        /// <param name="ApplicationName"></param>
        /// <returns></returns>
        public int GetProjectType()
        {
            // Get Project type Id 
            int ret = 0;

            try
            {
                var query = (int)(from p in this.mdb.AHSProjectTypes where (p.ApplicationName.ToLower() == this.ApplicationName.ToLower()) select p.Id).FirstOrDefault();
                if (query != 0)
                {
                    return query;
                }
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetProjectType error {0}", ex);
            }

            return ret;
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Add the list Users in to Project 
        /// </summary>
        /// <param name="mainPrjId"></param>
        /// <param name="idUserRoles"></param>
        /// <returns></returns>
        private int _AddUsersToProject(int mainPrjId, string[] idUserRoles)
        {
            try
            {
                foreach (var idUserRole in idUserRoles)
                {
                    // Format idUser^idRole
                    string[] arrUserRole = idUserRole.Split('^');

                    AHSDbContext.AHSUserInProject userInProject = new AHSDbContext.AHSUserInProject();

                    userInProject.Userid = Guid.Parse(arrUserRole[0]);
                    userInProject.Projectid = mainPrjId;

                    if ((arrUserRole[1] == null) || (arrUserRole[1].ToString() == "00000000-0000-0000-0000-000000000000"))
                    {
                        userInProject.Roleid = null;
                    }
                    else
                    {
                        userInProject.Roleid = Guid.Parse(arrUserRole[1]);
                    }

                    userInProject.IsInvite = false;
                    userInProject.Status = 1;

                    this.mdb.AHSUserInProjects.InsertOnSubmit(userInProject);
                }

                this.mdb.SubmitChanges();

                return 1;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager._AddUsersToProject error {0}", ex);

                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Add the list Organization and  Role of Organization in to Project 
        /// </summary>
        /// <param name="mainPrjId"></param>
        /// <param name="idOrgRoles"></param>
        /// <returns></returns>
        private int _AddOrgsToProject(int mainPrjId, string[] idOrgRoles)
        {
            try
            {
                foreach (var idOrgRole in idOrgRoles)
                {
                    // Format idOrg^idRole
                    string[] arrOrgRole = idOrgRole.Split('^');

                    AHSDbContext.AHSOrganizationInProject orgInProject = new AHSDbContext.AHSOrganizationInProject();

                    orgInProject.Orgid = Guid.Parse(arrOrgRole[0]);
                    orgInProject.Projectid = mainPrjId;

                    if ((arrOrgRole[1] == null) || (arrOrgRole[1].ToString() == "00000000-0000-0000-0000-000000000000"))
                    {
                        orgInProject.Roleid = null;

                    }
                    else
                    {
                        orgInProject.Roleid = Guid.Parse(arrOrgRole[1]);
                    }

                    orgInProject.IsInvite = false;
                    orgInProject.Status = 1;

                    this.mdb.AHSOrganizationInProjects.InsertOnSubmit(orgInProject);
                }

                this.mdb.SubmitChanges();

                return 1;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager._AddOrgsToProject error {0}", ex);

                return -1;
            }
        }
        #endregion

        /// <summary>
        /// Get Project by ProjectID
        /// </summary>
        /// <returns></returns>
        public AHSMainProject GetInfo(int projectID)
        {
            try
            {
                AHSMainProject ret = null;

                var prjs = from it in this.mdb.AHSMainProjects 
                           where it.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower() && 
                                it.Id == projectID 
                           select it;
                ret = (prjs != null && prjs.Count() > 0) ? prjs.FirstOrDefault() : null;

                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetInfo {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Get ProjectTypeID by ProjectTypeName
        /// </summary>
        /// <param name="projectTypeName">if projectTypeName is empty then get random projecttypeid </param>
        /// <returns></returns>
        public int GetProjectTypeID(string projectTypeName)
        {
            try
            {
                int ret = 0;

                if (!string.IsNullOrEmpty(projectTypeName))
                {
                    var pts = from pt in this.mdb.AHSProjectTypes
                              where (pt.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (pt.Name == projectTypeName)
                              select pt.Id;

                    ret = (pts != null && pts.Count() > 0) ? pts.FirstOrDefault() : 0;
                }
                else
                {
                    var pts = from pt in this.mdb.AHSProjectTypes
                              where (pt.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                              select pt.Id;

                    ret = (pts != null && pts.Count() > 0) ? pts.FirstOrDefault() : 0;
                }

                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetProjectTypeID {0}", ex);

                return 0;
            }
        }

        /// <summary>
        /// Get the ProjectID list by Project type
        /// </summary>
        /// <returns></returns>
        public List<int> GetProjectIDsByProjectType(string projectTypeName)
        {
            try
            {
                List<int> lst = new List<int>();

                var prjs = (from prj in this.mdb.AHSMainProjects
                           where (prj.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && 
                                (prj.AHSProjectType.Name.ToLower() == projectTypeName.ToLower())
                           select prj.Id).Distinct();

                foreach (var prj in prjs)
                {
                    lst.Add(prj);
                }

                return lst;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetProjectIDsByProjectType {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author:Hoang Van Tai
        /// Get list of the project by project type and linkProject
        /// </summary>
        /// <param name="projectTypeName"></param>
        /// <param name="linkProject"></param>
        /// <returns></returns>
        public List<Project> GetProjectsByProjectType(string projectTypeName, int linkProject)
        {
            try
            {
                List<Project> lst = new List<Project>();
                Guid owerId = _GetOwnerID(linkProject); // User or Organization 

                if (owerId != Guid.Empty)
                {
                    var prjs = (from prj in this.mdb.AHSMainProjects
                                where (prj.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) &&
                                      (prj.AHSProjectType.Name.ToLower() == projectTypeName.ToLower()) && ((prj.OwnerID == owerId) || (prj.OrgOwnerID == owerId))
                                select prj).Distinct();

                    foreach (var item in prjs)
                    {
                        Project entity = new Project();
                        string key = item.Id.ToString();

                        entity.Id = item.Id;
                        entity.Name = item.Name;
                        entity.Description = item.Description;
                        entity.DateCreated = item.DateCreated;
                        entity.EndDate = item.EndDate;
                        entity.Owner = item.Owner;
                        entity.OwnerIsUser = (item.OwnerIsUser != null && item.OwnerIsUser.Value);

                        if (item.OwnerID != null)
                        {
                            entity.OwnerId = item.OwnerID.Value;
                            entity.OwnerName = item.AHSAspnetMembership.AHSAspnetUser.Username;
                        }
                        else if (item.OrgOwnerID != null)
                        {
                            entity.OrgOwnerId = item.OrgOwnerID.Value;
                            entity.OwnerName = item.AHSOrganization.Name;
                        }

                        entity.ProjectTypeId = item.ProjectTypeID.HasValue ? item.ProjectTypeID : 0;
                        entity.ProjectTypeName = item.ProjectTypeID.HasValue ? item.AHSProjectType.Name : string.Empty;
                        entity.isPM = item.AHSProjectType.IsPM.HasValue ? item.AHSProjectType.IsPM.Value : false;
                        entity.RoleTypeId = (item.RoleTypeID != null) ? item.RoleTypeID : 0;

                        if (!string.IsNullOrEmpty(item.AHSProjectType.PathIcon)) entity.ProjectTypeIcon = item.AHSProjectType.PathIcon;

                        if (!string.IsNullOrEmpty(item.AHSProjectType.ApplicationURL)) entity.ApplicationURL = item.AHSProjectType.ApplicationURL;

                        lst.Add(entity);
                    }
                }

                return lst;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetProjectsByProjectType {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author:Hoang Van Tai
        /// Get list of the project by project type and ownerId
        /// </summary>
        /// <param name="projectTypeName"></param>
        /// <param name="ownerId"></param>
        /// <returns></returns>
        public List<Project> GetProjectsByProjectType(string projectTypeName, Guid ownerId)
        {
            try
            {
                List<Project> lst = new List<Project>();

                if (ownerId != Guid.Empty)
                {
                    var prjs = (from prj in this.mdb.AHSMainProjects
                                where (prj.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && 
                                      (prj.AHSProjectType.Name == projectTypeName) && ((prj.OwnerID == ownerId) || (prj.OrgOwnerID == ownerId))
                                select prj).Distinct();

                    foreach (var item in prjs)
                    {
                        Project entity = new Project();
                        string key = item.Id.ToString();

                        entity.Id = item.Id;
                        entity.Name = item.Name;
                        entity.Description = item.Description;
                        entity.DateCreated = item.DateCreated;
                        entity.EndDate = item.EndDate;
                        entity.Owner = item.Owner;
                        entity.OwnerIsUser = (item.OwnerIsUser != null && item.OwnerIsUser.Value);

                        if (item.OwnerID != null)
                        {
                            entity.OwnerId = item.OwnerID.Value;
                            entity.OwnerName = item.AHSAspnetMembership.AHSAspnetUser.Username;
                        }
                        else if (item.OrgOwnerID != null)
                        {
                            entity.OrgOwnerId = item.OrgOwnerID.Value;
                            entity.OwnerName = item.AHSOrganization.Name;
                        }

                        entity.ProjectTypeId = item.ProjectTypeID.HasValue ? item.ProjectTypeID : 0;
                        entity.ProjectTypeName = item.ProjectTypeID.HasValue ? item.AHSProjectType.Name : string.Empty;
                        entity.isPM = item.AHSProjectType.IsPM.HasValue ? item.AHSProjectType.IsPM.Value : false;
                        entity.RoleTypeId = (item.RoleTypeID != null) ? item.RoleTypeID : 0;

                        if (!string.IsNullOrEmpty(item.AHSProjectType.PathIcon)) entity.ProjectTypeIcon = item.AHSProjectType.PathIcon;

                        if (!string.IsNullOrEmpty(item.AHSProjectType.ApplicationURL)) entity.ApplicationURL = item.AHSProjectType.ApplicationURL;

                        lst.Add(entity);
                    }
                }

                return lst;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetProjectsByProjectType {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author:Hoang Van Tai
        /// Get list of the project by project type
        /// </summary>
        /// <param name="projectTypeName"></param>
        /// <returns></returns>
        public List<Project> GetProjectsByProjectType(string projectTypeName )
        {
            try
            {
                List<Project> lst = new List<Project>();

                var prjs = (from prj in this.mdb.AHSMainProjects
                            where (prj.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && 
                                  (prj.AHSProjectType.Name.ToLower() == projectTypeName.ToLower())
                            select prj ).Distinct();

                foreach (var item in prjs)
                {
                    Project entity = new Project();
                    string key = item.Id.ToString();

                    entity.Id = item.Id;
                    entity.Name = item.Name;
                    entity.Description = item.Description;
                    entity.DateCreated = item.DateCreated;
                    entity.EndDate = item.EndDate;
                    entity.Owner = item.Owner;
                    entity.OwnerIsUser = (item.OwnerIsUser != null && item.OwnerIsUser.Value);

                    if (item.OwnerID != null)
                    {
                        entity.OwnerId = item.OwnerID.Value;
                        entity.OwnerName = item.AHSAspnetMembership.AHSAspnetUser.Username;
                    }
                    else if (item.OrgOwnerID != null)
                    {
                        entity.OrgOwnerId = item.OrgOwnerID.Value;
                        entity.OwnerName = item.AHSOrganization.Name;
                    }

                    entity.ProjectTypeId = item.ProjectTypeID.HasValue ? item.ProjectTypeID : 0;
                    entity.ProjectTypeName = item.ProjectTypeID.HasValue ? item.AHSProjectType.Name : string.Empty;
                    entity.isPM = item.AHSProjectType.IsPM.HasValue ? item.AHSProjectType.IsPM.Value : false;
                    entity.RoleTypeId = (item.RoleTypeID != null) ? item.RoleTypeID : 0;

                    if (!string.IsNullOrEmpty(item.AHSProjectType.PathIcon)) entity.ProjectTypeIcon = item.AHSProjectType.PathIcon;

                    if (!string.IsNullOrEmpty(item.AHSProjectType.ApplicationURL)) entity.ApplicationURL = item.AHSProjectType.ApplicationURL;

                    lst.Add(entity);
                }

                return lst;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetProjectsByProjectType {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Check has the default project for application
        /// </summary>
        /// <returns></returns>
        public bool IsHasProjectDefault()
        {
            try
            {
                var prjs = from prj in this.mdb.AHSMainProjects
                           where prj.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()
                           select prj;

                return (prjs != null && prjs.Count() > 0);
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.IsHasProjectDefault {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Check exist project type
        /// </summary>
        /// <param name="projectTypeName"></param>
        /// <returns></returns>
        public bool IsExistProjectType(string projectTypeName)
        {
            try
            {
                return this.GetProjectTypeID(projectTypeName) != 0;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.IsExistProjectType error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Create project type
        /// </summary>
        /// <returns></returns>
        public bool CreateProjectType(string projectTypeName)
        {
            try
            {
                AHSProjectType pt = new AHSProjectType();

                pt.IsPM = false;
                pt.ApplicationName = this.ApplicationName;
                pt.Name = projectTypeName;
                pt.PathIcon = "";

                this.mdb.AHSProjectTypes.InsertOnSubmit(pt);

                this.mdb.SubmitChanges();

                return true;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.CreateProjectType error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Create Project
        /// </summary>
        /// <returns></returns>
        public int CreateProject(Guid userID, string name, string description, int projectTypeID)
        {
            try
            {
                AHSMainProject prj = new AHSMainProject();

                prj.Name = name.Trim();
                prj.Description = (description != null) ? description.Trim() : string.Empty;
                prj.Owner = string.Empty;
                prj.DateCreated = DateTime.Now;
                prj.Status = 0;
                prj.ProjectTypeID = projectTypeID;
                prj.OwnerIsUser = true;
                if (userID != Guid.Empty) prj.OwnerID = userID;

                this.mdb.AHSMainProjects.InsertOnSubmit(prj);

                this.mdb.SubmitChanges();

                return prj.Id;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.CreateProject error {0}", ex);

                return 0;
            }
        }

        /// <summary>
        /// Get ProjectID default for Application
        /// </summary>
        /// <returns>!=0 if has project default for application</returns>
        public int GetDefaultProjectID()
        {
            try
            {
                var prjs = from prj in this.mdb.AHSMainProjects
                           where  (prj.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                           select prj.Id;

                return (prjs != null && prjs.Count() > 0) ? prjs.FirstOrDefault() : 0;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetDefaultProjectID {0}", ex);

                return 0;
            }
        }

        /// <summary>
        /// Author:Hoang Van Tai
        /// Get the project list which contain user
        /// </summary>
        /// <param name="userID"></param>
        /// <returns></returns>
        /// Add:Hoang Van Tai
        /// Modify:
        public string GetProjectIdForUser(Guid userID)
        {
            try
            {
                var projects = (from uip in this.mdb.AHSUserInProjects
                                where (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (uip.Userid == userID)
                                select new { prjId = uip.Projectid, Name = uip.AHSMainProject.Name }).Distinct();

                string ret = "";
                string idPrjs;

                //Get list Project Id
                var sb = new System.Text.StringBuilder();

                foreach (var item in projects)
                {
                    sb.Append(item.prjId.ToString());
                    sb.Append(',');
                }

                idPrjs = sb.ToString();

                if (idPrjs.Trim() != "")
                {
                    ret = idPrjs.Substring(0, idPrjs.Length - 1);
                }

                sb = null;

                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetProjectIdForUser error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get the project for user
        /// </summary>
        /// <param name="ApplicationName"></param>
        /// <param name="username"></param>
        /// <param name="include_via_org"></param>
        /// <returns></returns>
        public Dictionary<string, Project> GetProjectForUser(string username, bool include_via_org = false)
        {
            try
            {
                Dictionary<string, Project> retLst = new Dictionary<string, Project>();
                UserManager um = new UserManager(this.ApplicationName);
                Guid userId = um.GetUserID(username);

                // Get userId is Owner 
                if (userId != Guid.Empty)
                {
                    //get project contain user
                    var uips = (from uip in this.mdb.AHSUserInProjects
                               where uip.Roleid.HasValue && (((uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) &&
                                    (uip.Userid == userId) && (uip.Status.HasValue) && (uip.Status.Value == 1)))
                               select new { project = uip.AHSMainProject, userid = uip.Userid, projectid = uip.AHSMainProject.Id, projectname = uip.AHSMainProject.Name, projecttype = uip.AHSMainProject.AHSProjectType.Name, rolenameforuserinproject = (uip.Roleid != null ? uip.AHSAspnetRole.Roledisplay : "not set role"), roleidforuserinproject = (uip.Roleid.HasValue ? uip.Roleid.Value : Guid.Empty) }).Distinct();

                    //(uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username.ToLower() == username.ToLower()) &&
                    foreach (var uip in uips)
                    {
                        Project entity = new Project();

                        string key = uip.roleidforuserinproject.ToString().Replace("-", "").ToUpper() + uip.projectid;
                        entity.Id = uip.project.Id;
                        entity.Name = uip.project.Name;
                        entity.Description = uip.project.Description;
                        entity.DateCreated = uip.project.DateCreated;
                        entity.EndDate = uip.project.EndDate;
                        entity.Owner = uip.project.Owner;
                        entity.OwnerIsUser = (uip.project.OwnerIsUser != null && uip.project.OwnerIsUser.Value);

                        if (uip.project.OwnerID != null)
                        {
                            entity.OwnerId = uip.project.OwnerID.Value;
                            entity.OwnerName = uip.project.AHSAspnetMembership.AHSAspnetUser.Username;
                        }

                        if (uip.project.OrgOwnerID != null)
                        {
                            entity.OrgOwnerId = uip.project.OrgOwnerID.Value;
                            entity.OwnerName = uip.project.AHSOrganization.Name;
                        }

                        entity.ProjectTypeId = uip.project.ProjectTypeID.HasValue ? uip.project.ProjectTypeID : 0;
                        entity.ProjectTypeName = uip.project.ProjectTypeID.HasValue ? uip.project.AHSProjectType.Name : string.Empty;
                        entity.isPM = uip.project.AHSProjectType.IsPM.HasValue ? uip.project.AHSProjectType.IsPM.Value : false;
                        entity.RoleTypeId = (uip.project.RoleTypeID != null) ? uip.project.RoleTypeID : 0;

                        if (!string.IsNullOrEmpty(uip.project.AHSProjectType.PathIcon)) entity.ProjectTypeIcon = uip.project.AHSProjectType.PathIcon;

                        if (!string.IsNullOrEmpty(uip.project.AHSProjectType.ApplicationURL)) entity.ApplicationURL = uip.project.AHSProjectType.ApplicationURL;

                        entity.RoleNameForUserInProject = uip.rolenameforuserinproject;
                        entity.RoleIDForUserInProject = uip.roleidforuserinproject;

                        if (!retLst.ContainsKey(key)) retLst.Add(key, entity);
                    }

                    if (include_via_org)
                    {
                        //Get project contain user thru organization
                        var oips = (from oip in this.mdb.AHSOrganizationInProjects
                                   join uio in this.mdb.AHSUsersInOrganizations on oip.Orgid equals uio.OrgId
                                   where oip.Roleid.HasValue && (((oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) &&
                                       (oip.Status.HasValue) && (oip.Status.Value == 1))) 
                                   select new { project = oip.AHSMainProject, orgid = oip.Orgid, projectid = oip.Projectid, projectname = oip.AHSMainProject.Name, projecttype = oip.AHSMainProject.AHSProjectType.Name, rolenameforuserinproject = (oip.Roleid != null ? oip.AHSAspnetRole.Rolename : "not set role"), roleidforuserinproject = (oip.Roleid.HasValue ? oip.Roleid.Value : Guid.Empty)}).Distinct();

                        foreach (var oip in oips)
                        {
                            Project entity = new Project();

                            string key = oip.roleidforuserinproject.ToString().Replace("-", "").ToUpper() + oip.projectid;
                            entity.Id = oip.project.Id;
                            entity.Name = oip.project.Name;
                            entity.Description = oip.project.Description;
                            entity.DateCreated = oip.project.DateCreated;
                            entity.EndDate = oip.project.EndDate;
                            entity.Owner = oip.project.Owner;
                            entity.OwnerIsUser = (oip.project.OwnerIsUser != null && oip.project.OwnerIsUser.Value);

                            if (oip.project.OwnerID != null)
                            {
                                entity.OwnerId = oip.project.OwnerID.Value;
                                entity.OwnerName = oip.project.AHSAspnetMembership.AHSAspnetUser.Username;
                            }

                            if (oip.project.OrgOwnerID != null)
                            {
                                entity.OrgOwnerId = oip.project.OrgOwnerID.Value;
                                entity.OwnerName = oip.project.AHSOrganization.Name;
                            }

                            entity.ProjectTypeId = oip.project.ProjectTypeID.HasValue ? oip.project.ProjectTypeID : 0;
                            entity.ProjectTypeName = oip.project.ProjectTypeID.HasValue ? oip.project.AHSProjectType.Name : string.Empty;
                            entity.isPM = oip.project.AHSProjectType.IsPM.HasValue ? oip.project.AHSProjectType.IsPM.Value : false;
                            entity.RoleTypeId = (oip.project.RoleTypeID != null) ? oip.project.RoleTypeID : 0;
                            entity.RoleIDForUserInProject = oip.roleidforuserinproject;
                            entity.RoleNameForUserInProject = oip.rolenameforuserinproject;

                            if (!string.IsNullOrEmpty(oip.project.AHSProjectType.PathIcon)) entity.ProjectTypeIcon = oip.project.AHSProjectType.PathIcon;

                            if (!string.IsNullOrEmpty(oip.project.AHSProjectType.ApplicationURL)) entity.ApplicationURL = oip.project.AHSProjectType.ApplicationURL;

                            if (!retLst.ContainsKey(key)) retLst.Add(key, entity);
                        }
                    }
                }

                return retLst;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetProjectForUser error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author:Hoang Van Tai
        /// Get the project that to invited for user  
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public Dictionary<string, Project> GetProjectInvitedForUser(string userId)
        {
            try
            {
                Dictionary<string, Project> ret= new Dictionary<string, Project>();
                UserManager um = new UserManager(this.ApplicationName);

                //get project contain user
                var uips = (from uip in this.mdb.AHSUserInProjects
                           where (((uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) &&
                                (uip.Userid  == Guid.Parse(userId)) && (uip.Status.HasValue) && (uip.Status.Value == -1)))
                           select new { project = uip.AHSMainProject, userid = uip.Userid, rolenameforuserinproject = (uip.Roleid != null ? uip.AHSAspnetRole.Roledisplay : "not set role"), roleidforuserinproject = (uip.Roleid.HasValue ? uip.Roleid.Value : Guid.Empty)}).Distinct();

                foreach (var item in uips)
                {
                        Project entity = new Project();

                        string key = item.project.Id.ToString();
                        entity.Id = item.project.Id;
                        entity.Name = item.project.Name;

                        entity.Description = item.project.Description;
                        entity.DateCreated = item.project.DateCreated;
                        entity.EndDate = item.project.EndDate;
                        entity.Owner = item.project.Owner;
                        entity.OwnerIsUser = (item.project.OwnerIsUser != null && item.project.OwnerIsUser.Value);

                        if (item.project.OwnerID != null)
                        {
                            entity.OwnerId = item.project.OwnerID.Value;
                            entity.OwnerName = item.project.AHSAspnetMembership.AHSAspnetUser.Username;
                        }

                        if (item.project.OrgOwnerID != null)
                        {
                            entity.OrgOwnerId = item.project.OrgOwnerID.Value;
                            entity.OwnerName = item.project.AHSOrganization.Name;
                        }

                        entity.ProjectTypeId = item.project.ProjectTypeID.HasValue ? item.project.ProjectTypeID : 0;
                        entity.ProjectTypeName = item.project.ProjectTypeID.HasValue ? item.project.AHSProjectType.Name : string.Empty;
                        entity.isPM = item.project.AHSProjectType.IsPM.HasValue ? item.project.AHSProjectType.IsPM.Value : false;
                        entity.RoleTypeId = (item.project.RoleTypeID != null) ? item.project.RoleTypeID : 0;

                        entity.RoleNameForUserInProject = item.rolenameforuserinproject;
                        entity.RoleIDForUserInProject = item.roleidforuserinproject;

                        if (!ret.ContainsKey(key)) ret.Add(key, entity);
                }

                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetProjectInvitedForUser error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author:Hoang Van Tai
        /// private GetOwnerID
        /// </summary>
        /// <param name="linkProject"></param>
        /// <returns></returns>
        private Guid _GetOwnerID(int linkProject)
        {
            Guid ownerId = Guid.Empty;

            try
            {
                var prj = (from prjs in this.mdb.AHSMainProjects
                           where (prjs.Id == linkProject) && (prjs.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                           select prjs).FirstOrDefault();

                if (prj != null)
                {
                    //Owner is user
                    if (prj.OwnerID != null)
                    {
                        ownerId= prj.OwnerID.Value;
                    }
                    else if (prj.OrgOwnerID != null) 
                    {
                        //Owner is Organization
                        ownerId= prj.OrgOwnerID.Value;
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetOwnerID {0}", ex);
            }

            return ownerId;
        }
        
        /// <summary>
        /// Author: Hoang Van Tai
        /// Get the project for user and role
        /// </summary>
        /// <param name="username"></param>
        /// <param name="rolename"></param>
        /// <param name="include_via_org"></param>
        /// <returns></returns>
        public int[] GetProjectForUser(string username, string rolename, string projectType, int linkProject, bool include_via_org = false)
        {
            try
            {
                List<int> projs = new List<int>();
                UserManager um = new UserManager(this.ApplicationName);
				// User or Organization 
                Guid owerId = _GetOwnerID(linkProject);

                // Get owerId is Owner 
                if (owerId != Guid.Empty)
                {
                    //get project contain user
                    var uips = (from uip in this.mdb.AHSUserInProjects
                                where (((uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) &&
                                     (uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username.ToLower() == username.ToLower()) && (uip.AHSAspnetRole.Rolename == rolename) &&
                                     (uip.Status.HasValue) && (uip.Status.Value == 1)  && (uip.AHSMainProject.AHSProjectType.Name.ToLower() ==projectType.ToLower())) && 
                                     ((uip.AHSMainProject.OwnerID == owerId) || (uip.AHSMainProject.OrgOwnerID == owerId)) && uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                select new { projectid = uip.AHSMainProject.Id }).Distinct();

                    foreach (var item in uips)
                    {
                        projs.Add(item.projectid);
                    }

                    if (include_via_org)
                    {
                        //Get project contain user thru organization
                        var oips = (from oip in this.mdb.AHSOrganizationInProjects
                                   join uio in this.mdb.AHSUsersInOrganizations on oip.Orgid equals uio.OrgId
                                   where (((oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) &&
                                   (oip.Status.HasValue) && (oip.Status.Value == 1) && (uio.Status.HasValue && uio.Status.Value == 1) && (oip.AHSAspnetRole.Rolename == rolename) &&
                                   (uio.AHSAspnetUser.Username.ToLower() == username.ToLower())) &&
                                   (((oip.AHSMainProject.OwnerID == owerId) || (oip.AHSMainProject.OrgOwnerID == owerId))  && oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()))
                                   select new { projectid = oip.Projectid }).Distinct();

                        foreach (var item in oips)
                        {
                            
                            if (!projs.Contains(item.projectid)) projs.Add(item.projectid);
                        }
                    }
                }

                return projs.ToArray();
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetProjectForUser error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get the project for user, role, projecttype, ownerId
        /// </summary>
        /// <param name="username"></param>
        /// <param name="rolename"></param>
        /// <param name="projectType"></param>
        /// <param name="owerId"></param>
        /// <param name="include_via_org"></param>
        /// <returns></returns>
        public List<Project> GetProjectForUser(string username, string rolename, string projectType, Guid owerId, bool include_via_org = false)
        {
            try
            {
                List<Project> ret = new List<Project>();

                // Get owerId is Owner 
                if (owerId != Guid.Empty)
                {
                    //get project contain user
                    var uips = (from uip in this.mdb.AHSUserInProjects
                                where (((uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) &&
                                     (uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username.ToLower() == username.ToLower()) && (uip.AHSAspnetRole.Rolename == rolename) &&
                                     (uip.Status.HasValue) && (uip.Status.Value == 1) && (uip.AHSMainProject.AHSProjectType.Name.ToLower() == projectType.ToLower())) && 
                                     ((uip.AHSMainProject.OwnerID == owerId) || (uip.AHSMainProject.OrgOwnerID == owerId)) && 
                                     uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                select new { project = uip.AHSMainProject}).Distinct();

                    foreach (var item in uips)
                    {
                        Project entity = new Project();

                        entity.Id = item.project.Id;
                        entity.Name = item.project.Name;
                        entity.Description = item.project.Description;
                        entity.DateCreated = item.project.DateCreated;
                        entity.EndDate = item.project.EndDate;
                        entity.Owner = item.project.Owner;
                        entity.OwnerIsUser = (item.project.OwnerIsUser != null && item.project.OwnerIsUser.Value);

                        if (item.project.OwnerID != null)
                        {
                            entity.OwnerId = item.project.OwnerID.Value;
                            entity.OwnerName = item.project.AHSAspnetMembership.AHSAspnetUser.Username;
                        }

                        if (item.project.OrgOwnerID != null)
                        {
                            entity.OrgOwnerId = item.project.OrgOwnerID.Value;
                            entity.OwnerName = item.project.AHSOrganization.Name;
                        }

                        entity.ProjectTypeId = item.project.ProjectTypeID.HasValue ? item.project.ProjectTypeID : 0;
                        entity.ProjectTypeName = item.project.ProjectTypeID.HasValue ? item.project.AHSProjectType.Name : string.Empty;
                        entity.isPM = item.project.AHSProjectType.IsPM.HasValue ? item.project.AHSProjectType.IsPM.Value : false;
                        entity.RoleTypeId = (item.project.RoleTypeID != null) ? item.project.RoleTypeID : 0;

                        if (!string.IsNullOrEmpty(item.project.AHSProjectType.PathIcon)) entity.ProjectTypeIcon = item.project.AHSProjectType.PathIcon;

                        if (!string.IsNullOrEmpty(item.project.AHSProjectType.ApplicationURL)) entity.ApplicationURL = item.project.AHSProjectType.ApplicationURL;

                        ret.Add(entity);
                    }

                    if (include_via_org)
                    {
                        //Get project contain user thru organization
                        var oips = (from oip in this.mdb.AHSOrganizationInProjects
                                   join uio in this.mdb.AHSUsersInOrganizations on oip.Orgid equals uio.OrgId
                                   where (((oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) &&
                                        (oip.Status.HasValue) && (oip.Status.Value == 1) && (uio.Status.HasValue && uio.Status.Value == 1) && (oip.AHSAspnetRole.Rolename == rolename) &&
                                        (uio.AHSAspnetUser.Username.ToLower() == username.ToLower())) &&
                                        (((oip.AHSMainProject.OwnerID == owerId) || (oip.AHSMainProject.OrgOwnerID == owerId)) && 
                                        oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()))
                                    select new { project = oip.AHSMainProject }).Distinct();

                        foreach (var item in oips)
                        {
                            Project entity = new Project();

                            entity.Id = item.project.Id;
                            entity.Name = item.project.Name;
                            entity.Description = item.project.Description;
                            entity.DateCreated = item.project.DateCreated;
                            entity.EndDate = item.project.EndDate;
                            entity.Owner = item.project.Owner;
                            entity.OwnerIsUser = (item.project.OwnerIsUser != null && item.project.OwnerIsUser.Value);

                            if (item.project.OwnerID != null)
                            {
                                entity.OwnerId = item.project.OwnerID.Value;
                                entity.OwnerName = item.project.AHSAspnetMembership.AHSAspnetUser.Username;
                            }

                            if (item.project.OrgOwnerID != null)
                            {
                                entity.OrgOwnerId = item.project.OrgOwnerID.Value;
                                entity.OwnerName = item.project.AHSOrganization.Name;
                            }

                            entity.ProjectTypeId = item.project.ProjectTypeID.HasValue ? item.project.ProjectTypeID : 0;
                            entity.ProjectTypeName = item.project.ProjectTypeID.HasValue ? item.project.AHSProjectType.Name : string.Empty;
                            entity.isPM = item.project.AHSProjectType.IsPM.HasValue ? item.project.AHSProjectType.IsPM.Value : false;
                            entity.RoleTypeId = (item.project.RoleTypeID != null) ? item.project.RoleTypeID : 0;

                            if (!string.IsNullOrEmpty(item.project.AHSProjectType.PathIcon)) entity.ProjectTypeIcon = item.project.AHSProjectType.PathIcon;

                            if (!string.IsNullOrEmpty(item.project.AHSProjectType.ApplicationURL)) entity.ApplicationURL = item.project.AHSProjectType.ApplicationURL;

                            if (!ret.Contains(entity)) ret.Add(entity);
                        }
                    }
                }

                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetProjectForUser error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get the project for user, projecttype
        /// </summary>
        /// <param name="username"></param>
        /// <param name="projectType"></param>
        /// <param name="include_via_org"></param>
        /// <returns></returns>
        public List<Project> GetProjectForUser(string username, string projectType, bool include_via_org = false)
        {
            try
            {
                List<Project> ret = new List<Project>();
                
                    //get project contain user
                    var uips = (from uip in this.mdb.AHSUserInProjects
                                where (((uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) &&
                                     (uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username.ToLower() == username.ToLower()) &&
                                     (uip.Status.HasValue) && (uip.Status.Value == 1) && 
                                     (uip.AHSMainProject.AHSProjectType.Name.ToLower() == projectType.ToLower())))
                                select new { project = uip.AHSMainProject}).Distinct();
                
                foreach (var item in uips)
                    {

                        Project entity = new Project();

                        entity.Id = item.project.Id;
                        entity.Name = item.project.Name;
                        entity.Description = item.project.Description;
                        entity.DateCreated = item.project.DateCreated;
                        entity.EndDate = item.project.EndDate;
                        entity.Owner = item.project.Owner;
                        entity.OwnerIsUser = (item.project.OwnerIsUser != null && item.project.OwnerIsUser.Value);

                        if (item.project.OwnerID != null)
                        {
                            entity.OwnerId = item.project.OwnerID.Value;
                            entity.OwnerName = item.project.AHSAspnetMembership.AHSAspnetUser.Username;
                        }

                        if (item.project.OrgOwnerID != null)
                        {
                            entity.OrgOwnerId = item.project.OrgOwnerID.Value;
                            entity.OwnerName = item.project.AHSOrganization.Name;
                        }

                        entity.ProjectTypeId = item.project.ProjectTypeID.HasValue ? item.project.ProjectTypeID : 0;
                        entity.ProjectTypeName = item.project.ProjectTypeID.HasValue ? item.project.AHSProjectType.Name : string.Empty;
                        entity.isPM = item.project.AHSProjectType.IsPM.HasValue ? item.project.AHSProjectType.IsPM.Value : false;
                        entity.RoleTypeId = (item.project.RoleTypeID != null) ? item.project.RoleTypeID : 0;

                        if (!string.IsNullOrEmpty(item.project.AHSProjectType.PathIcon)) entity.ProjectTypeIcon = item.project.AHSProjectType.PathIcon;

                        if (!string.IsNullOrEmpty(item.project.AHSProjectType.ApplicationURL)) entity.ApplicationURL = item.project.AHSProjectType.ApplicationURL;

                        ret.Add(entity);
                    }

                    if (include_via_org)
                    {
                        //Get project contain user thru organization
                        var oips = (from oip in this.mdb.AHSOrganizationInProjects
                                   join uio in this.mdb.AHSUsersInOrganizations on oip.Orgid equals uio.OrgId
                                   where (((oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) &&
                                        (oip.Status.HasValue) && (oip.Status.Value == 1) && (uio.Status.HasValue && uio.Status.Value == 1) &&
                                        (uio.AHSAspnetUser.Username.ToLower() == username.ToLower())))
                                   select new { project = oip.AHSMainProject }).Distinct();

                        foreach (var item in oips)
                        {
                            Project entity = new Project();

                            entity.Id = item.project.Id;
                            entity.Name = item.project.Name;
                            entity.Description = item.project.Description;
                            entity.DateCreated = item.project.DateCreated;
                            entity.EndDate = item.project.EndDate;
                            entity.Owner = item.project.Owner;
                            entity.OwnerIsUser = (item.project.OwnerIsUser != null && item.project.OwnerIsUser.Value);

                            if (item.project.OwnerID != null)
                            {
                                entity.OwnerId = item.project.OwnerID.Value;
                                entity.OwnerName = item.project.AHSAspnetMembership.AHSAspnetUser.Username;
                            }

                            if (item.project.OrgOwnerID != null)
                            {
                                entity.OrgOwnerId = item.project.OrgOwnerID.Value;
                                entity.OwnerName = item.project.AHSOrganization.Name;
                            }

                            entity.ProjectTypeId = item.project.ProjectTypeID.HasValue ? item.project.ProjectTypeID : 0;
                            entity.ProjectTypeName = item.project.ProjectTypeID.HasValue ? item.project.AHSProjectType.Name : string.Empty;
                            entity.isPM = item.project.AHSProjectType.IsPM.HasValue ? item.project.AHSProjectType.IsPM.Value : false;
                            entity.RoleTypeId = (item.project.RoleTypeID != null) ? item.project.RoleTypeID : 0;

                            if (!string.IsNullOrEmpty(item.project.AHSProjectType.PathIcon)) entity.ProjectTypeIcon = item.project.AHSProjectType.PathIcon;

                            if (!string.IsNullOrEmpty(item.project.AHSProjectType.ApplicationURL)) entity.ApplicationURL = item.project.AHSProjectType.ApplicationURL;

                            if (!ret.Contains(entity)) ret.Add(entity);
                        }
                    }

                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetProjectForUser error {0}", ex);

                return null;
            }
        }
        
        /// <summary>
        /// Author: Hoang Van Tai
        /// Get the project for user not by role
        /// </summary>
        /// <param name="ApplicationName"></param>
        /// <param name="username"></param>
        /// <param name="include_via_org"></param>
        /// <returns></returns>
        public Dictionary<string, Project> GetProjectForUserNotByRole(string username, bool include_via_org = false)
        {
            try
            {
                Dictionary<string, Project> retLst = new Dictionary<string, Project>();
                UserManager um = new UserManager(this.ApplicationName);
                Guid userId = um.GetUserID(username);

                // Get userId is Owner 
                if (userId != Guid.Empty)
                {
                    //get project contain user
                    var uips = (from uip in this.mdb.AHSUserInProjects
                               where (((uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) &&
                                    (uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username.ToLower() == username.ToLower()) &&
                                    (uip.Status.HasValue) && (uip.Status.Value == 1)) ||
                                    (uip.AHSMainProject.OwnerID == userId) && uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                               select new { project = uip.AHSMainProject, userid = uip.Userid, projectid = uip.AHSMainProject.Id, projectname = uip.AHSMainProject.Name, projecttype = uip.AHSMainProject.AHSProjectType.Name}).Distinct();

                    foreach (var uip in uips)
                    {
                        Project entity = new Project();

                        string key = uip.projectid.ToString();
                        entity.Id = uip.project.Id;
                        entity.Name = uip.project.Name;
                        entity.Description = uip.project.Description;
                        entity.DateCreated = uip.project.DateCreated;
                        entity.EndDate = uip.project.EndDate;
                        entity.Owner = uip.project.Owner;
                        entity.OwnerIsUser = (uip.project.OwnerIsUser != null && uip.project.OwnerIsUser.Value);

                        if (uip.project.OwnerID != null)
                        {
                            entity.OwnerId = uip.project.OwnerID.Value;
                            entity.OwnerName = uip.project.AHSAspnetMembership.AHSAspnetUser.Username;
                        }

                        if (uip.project.OrgOwnerID != null)
                        {
                            entity.OrgOwnerId = uip.project.OrgOwnerID.Value;
                            entity.OwnerName = uip.project.AHSOrganization.Name;
                        }

                        entity.ProjectTypeId = uip.project.ProjectTypeID.HasValue ? uip.project.ProjectTypeID : 0;
                        entity.ProjectTypeName = uip.project.ProjectTypeID.HasValue ? uip.project.AHSProjectType.Name : string.Empty;
                        entity.isPM = uip.project.AHSProjectType.IsPM.HasValue ? uip.project.AHSProjectType.IsPM.Value : false;
                        entity.RoleTypeId = (uip.project.RoleTypeID != null) ? uip.project.RoleTypeID : 0;

                        if (!string.IsNullOrEmpty(uip.project.AHSProjectType.PathIcon)) entity.ProjectTypeIcon = uip.project.AHSProjectType.PathIcon;

                        if (!string.IsNullOrEmpty(uip.project.AHSProjectType.ApplicationURL)) entity.ApplicationURL = uip.project.AHSProjectType.ApplicationURL;


                        if (!retLst.ContainsKey(key)) retLst.Add(key, entity);
                    }
                    
                    // Get project have only owner:
                    var ums = (from mp in this.mdb.AHSMainProjects
                              where (mp.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) &&
                                    (mp.OwnerID == userId)
                              select new { project = mp, projectid = mp.Id, projectname = mp.Name, projecttype = mp.AHSProjectType.Name }).Distinct();

                    foreach (var item in ums)
                    {
                        Project entity = new Project();

                        string key = item.projectid.ToString();
                        entity.Id = item.project.Id;
                        entity.Name = item.project.Name;
                        entity.Description = item.project.Description;
                        entity.DateCreated = item.project.DateCreated;
                        entity.EndDate = item.project.EndDate;
                        entity.Owner = item.project.Owner;
                        entity.OwnerIsUser = (item.project.OwnerIsUser != null && item.project.OwnerIsUser.Value);

                        if (item.project.OwnerID != null)
                        {
                            entity.OwnerId = item.project.OwnerID.Value;
                            entity.OwnerName = item.project.AHSAspnetMembership.AHSAspnetUser.Username;
                        }

                        if (item.project.OrgOwnerID != null)
                        {
                            entity.OrgOwnerId = item.project.OrgOwnerID.Value;
                            entity.OwnerName = item.project.AHSOrganization.Name;
                        }

                        entity.ProjectTypeId = item.project.ProjectTypeID.HasValue ? item.project.ProjectTypeID : 0;
                        entity.ProjectTypeName = item.project.ProjectTypeID.HasValue ? item.project.AHSProjectType.Name : string.Empty;
                        entity.isPM = item.project.AHSProjectType.IsPM.HasValue ? item.project.AHSProjectType.IsPM.Value : false;
                        entity.RoleTypeId = (item.project.RoleTypeID != null) ? item.project.RoleTypeID : 0;

                        if (!string.IsNullOrEmpty(item.project.AHSProjectType.PathIcon)) entity.ProjectTypeIcon = item.project.AHSProjectType.PathIcon;

                        if (!string.IsNullOrEmpty(item.project.AHSProjectType.ApplicationURL)) entity.ApplicationURL = item.project.AHSProjectType.ApplicationURL;


                        if (!retLst.ContainsKey(key)) retLst.Add(key, entity);
                    }
                    

                    if (include_via_org)
                    {
                        //Get project contain user thru organization
                        var oips = (from oip in this.mdb.AHSOrganizationInProjects
                                   join uio in this.mdb.AHSUsersInOrganizations on oip.Orgid equals uio.OrgId
                                   where (((oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) &&
                                        (oip.Status.HasValue) && (oip.Status.Value == 1) && (uio.Status.HasValue && uio.Status.Value == 1) &&
                                        (uio.AHSAspnetUser.Username.ToLower() == username.ToLower())) || (oip.AHSMainProject.OwnerID == userId && 
                                        oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()))
                                   select new { project = oip.AHSMainProject, orgid = oip.Orgid, projectid = oip.Projectid, projectname = oip.AHSMainProject.Name, projecttype = oip.AHSMainProject.AHSProjectType.Name, rolenameforuserinproject = (oip.Roleid != null ? oip.AHSAspnetRole.Rolename : "not set role"), roleidforuserinproject = (oip.Roleid.HasValue ? oip.Roleid.Value : Guid.Empty) }).Distinct();

                        foreach (var oip in oips)
                        {
                            Project entity = new Project();

                            string key = oip.projectid.ToString();
                            entity.Id = oip.project.Id;
                            entity.Name = oip.project.Name;
                            entity.Description = oip.project.Description;
                            entity.DateCreated = oip.project.DateCreated;
                            entity.EndDate = oip.project.EndDate;
                            entity.Owner = oip.project.Owner;
                            entity.OwnerIsUser = (oip.project.OwnerIsUser != null && oip.project.OwnerIsUser.Value);

                            if (oip.project.OwnerID != null)
                            {
                                entity.OwnerId = oip.project.OwnerID.Value;
                                entity.OwnerName = oip.project.AHSAspnetMembership.AHSAspnetUser.Username;
                            }

                            if (oip.project.OrgOwnerID != null)
                            {
                                entity.OrgOwnerId = oip.project.OrgOwnerID.Value;
                                entity.OwnerName = oip.project.AHSOrganization.Name;
                            }

                            entity.ProjectTypeId = oip.project.ProjectTypeID.HasValue ? oip.project.ProjectTypeID : 0;
                            entity.ProjectTypeName = oip.project.ProjectTypeID.HasValue ? oip.project.AHSProjectType.Name : string.Empty;
                            entity.isPM = oip.project.AHSProjectType.IsPM.HasValue ? oip.project.AHSProjectType.IsPM.Value : false;
                            entity.RoleTypeId = (oip.project.RoleTypeID != null) ? oip.project.RoleTypeID : 0;
                            entity.RoleIDForUserInProject = oip.roleidforuserinproject;
                            entity.RoleNameForUserInProject = oip.rolenameforuserinproject;

                            if (!string.IsNullOrEmpty(oip.project.AHSProjectType.PathIcon)) entity.ProjectTypeIcon = oip.project.AHSProjectType.PathIcon;

                            if (!string.IsNullOrEmpty(oip.project.AHSProjectType.ApplicationURL)) entity.ApplicationURL = oip.project.AHSProjectType.ApplicationURL;

                            if (!retLst.ContainsKey(key)) retLst.Add(key, entity);
                        }
                    }
                }

                return retLst;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetProjectForUserNotByRole error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get the list project for Application and OrgId
        /// </summary>
        /// <param name="ApplicationName"></param>
        /// <param name="OrgId"></param>
        /// <returns></returns>
        public Dictionary<int, Project> GetProjectForOrganization(Guid OrgId)
        {
            try
            {
                Dictionary<int, Project> lst = new Dictionary<int, Project>();

                var projects = (from project in this.mdb.AHSOrganizationInProjects
                               where (project.Orgid == OrgId) && (project.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && 
                                     (project.Status.HasValue && project.Status.Value == 1)
                               select new { prj = project.AHSMainProject, role = project.AHSAspnetRole }).Distinct();

                foreach (var project in projects)
                {
                    if (!lst.ContainsKey(project.prj.Id))
                    {
                        Project entity = new Project();

                        entity.Id = project.prj.Id;
                        entity.Name = project.prj.Name;
                        entity.Description = project.prj.Description;
                        entity.DateCreated = project.prj.DateCreated;
                        entity.EndDate = project.prj.EndDate;
                        entity.Owner = project.prj.Owner;
                        entity.OwnerIsUser = (project.prj.OwnerIsUser != null && project.prj.OwnerIsUser.Value);

                        if (project.prj.OwnerID != null)
                        {
                            entity.OwnerId = project.prj.OwnerID.Value;
                            entity.OwnerName = project.prj.AHSAspnetMembership.AHSAspnetUser.Username;
                        }

                        if (project.prj.OrgOwnerID != null)
                        {
                            entity.OrgOwnerId = project.prj.OrgOwnerID.Value;
                            entity.OwnerName = project.prj.AHSOrganization.Name;
                        }

                        entity.ProjectTypeId = project.prj.ProjectTypeID.HasValue ? project.prj.ProjectTypeID : 0;
                        entity.ProjectTypeName = project.prj.ProjectTypeID.HasValue ? project.prj.AHSProjectType.Name : string.Empty;
                        entity.isPM = project.prj.AHSProjectType.IsPM.HasValue ? project.prj.AHSProjectType.IsPM.Value : false;
                        entity.RoleTypeId = (project.prj.RoleTypeID != null) ? project.prj.RoleTypeID : 0;

                        if (!string.IsNullOrEmpty(project.prj.AHSProjectType.PathIcon)) entity.ProjectTypeIcon = project.prj.AHSProjectType.PathIcon;

                        if (!string.IsNullOrEmpty(project.prj.AHSProjectType.ApplicationURL)) entity.ApplicationURL = project.prj.AHSProjectType.ApplicationURL;

                        if (project.role != null)
                        {
                            entity.RoleIDForUserInProject = project.role.Roleid;
                            entity.RoleNameForUserInProject = string.IsNullOrEmpty(project.role.Roledisplay) ? project.role.Rolename : project.role.Roledisplay;
                        }

                        lst.Add(project.prj.Id, entity);
                    }
                }

                return lst;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetProjectForOrganization error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Delete the project for ProjectID and ApplicationName
        /// </summary>
        /// <param name="ProjectID"></param>
        /// <returns></returns>
        public bool DeleteProject(int ProjectID)
        {
            try
            {
                var prjs = from prj in this.mdb.AHSMainProjects
                           where (prj.Id == ProjectID) && (prj.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                           select prj;

                this.mdb.AHSMainProjects.DeleteAllOnSubmit(prjs);

                this.mdb.SubmitChanges();

                return true;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();

                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.DeleteProject error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Delete the project for ProjectID and ApplicationName 
        /// </summary>
        /// <param name="ProjectID"></param>
        /// <returns></returns>
        public bool DeleteProjectForApplication(int ProjectID)
        {
            try
            {
                var prjs = from prj in this.mdb.AHSMainProjects
                           where (prj.Id == ProjectID) && (prj.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                           select prj;

                this.mdb.AHSMainProjects.DeleteAllOnSubmit(prjs);

                this.mdb.SubmitChanges();

                return true;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();

                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.DeleteProjectForApplication error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Add the project and list Id user and Role of user, list Id Organization and role of organization 
        /// </summary>
        /// <param name="ApplicationName"></param>
        /// <param name="name"></param>
        /// <param name="description"></param>
        /// <param name="owner"></param>
        /// <param name="idUserRoles"></param>
        /// <param name="idOrgRoles"></param>
        /// <returns></returns>
        public int AddProject(string name, string description, string owner, string[] idUserRoles, string[] idOrgRoles)
        {
            // Add project 
            try
            {
                AHSMainProject prj = new AHSMainProject();
                UserManager user = new UserManager(this.ApplicationName);
                Guid _ownerId;
                int newMainPrj = 0;

                prj.Name = name.Trim();
                prj.Description = (description != null) ? description.Trim() : string.Empty;
                prj.Owner = string.Empty;

                // set owner is user 
                if (owner != null)
                {
                    _ownerId = user.GetUserID(owner);

                    // If ownerId is not Empty 
                    if (_ownerId != Guid.Empty)
                    {
                        prj.OwnerID = _ownerId;
                    }
                }

                prj.DateCreated = DateTime.Now;
                prj.Status = 0;
                prj.ProjectTypeID = GetProjectType();
                prj.OwnerIsUser = true;

                this.mdb.AHSMainProjects.InsertOnSubmit(prj);

                this.mdb.SubmitChanges();

                newMainPrj = _GetNewMainPrjByName(name.Trim());

                //Update UserRoles
                if ((idUserRoles != null) && (newMainPrj > 0))
                {
                    _AddUsersToProject(newMainPrj, idUserRoles);
                }

                if ((idOrgRoles != null) && (newMainPrj > 0))
                {
                    _AddOrgsToProject(newMainPrj, idOrgRoles);
                }

                return newMainPrj;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.AddProject error {0}", ex);

                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Update the project
        /// </summary>
        /// <param name="ApplicationName"></param>
        /// <param name="mainPrjId"></param>
        /// <param name="name"></param>
        /// <param name="description"></param>
        /// <param name="owner"></param>
        /// <param name="idUserRoles"></param>
        /// <param name="idOrgRoles"></param>
        /// <returns></returns>
        public int UpdateProject(int mainPrjId, string name, string description, string owner, string[] idUserRoles, string[] idOrgRoles)
        {
            try
            {
                var prjs = (from p in this.mdb.AHSMainProjects
                            where (p.Id == mainPrjId)
                            select p).FirstOrDefault();

                UserManager user = new UserManager(this.ApplicationName);
                Guid _ownerId;

                // If exists prjs then update project
                if (prjs != null)
                {
                    prjs.Name = name.Trim();
                    prjs.Description = (description != null) ? description.Trim() : string.Empty;

                    // set owner is user 
                    if (owner != null)
                    {
                        _ownerId = user.GetUserID(owner);

                        // If ownerId is not Empty 
                        if (_ownerId != Guid.Empty)
                        {
                            prjs.OwnerID = _ownerId;
                        }
                    }

                    prjs.ProjectTypeID = GetProjectType();

                    this.mdb.SubmitChanges();

                    // Remove Users to project 
                    _RemoveUsersToProject(mainPrjId, idUserRoles);

                    //Update UserRoles
                    if (idUserRoles != null)
                    {
                        _UpdateUsersToProject(mainPrjId, idUserRoles);
                    }

                    // Remove Org to project
                    _RemoveOrgsToProject(mainPrjId, idOrgRoles);

                    if (idOrgRoles != null)
                    {
                        _UpdateOrgsToProject(mainPrjId, idOrgRoles);
                    }
                }

                return mainPrjId;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();

                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UpdateProject error {0}", ex);

                return -1;
            }
        }
        /// <summary>
        /// Author: Hoang Van Tai
        /// Search list project by SA
        /// </summary>
        /// <param name="keyword"></param>
        /// <param name="prjtype"></param>
        /// <returns></returns>
        public List<Project> SearchListBySA(string keyword, int prjtype)
        {
            try
            {
                List<Project> ret = new List<Project>();
                IEnumerable<AHSMainProject> projects = null;

                if ((keyword != null) && (prjtype != 0))
                {
                    //Select the project by name, projecttype, use is owner by name, organization is owner by name  
                    projects = (from mp in this.mdb.AHSMainProjects
                               where (mp.ProjectTypeID == prjtype && (mp.Name.ToLower().Contains(keyword) || mp.Description.ToLower().Contains(keyword) || 
                                     (mp.OwnerID.HasValue && mp.AHSAspnetMembership.AHSAspnetUser.Username.ToLower().Contains(keyword)) || 
                                     (mp.OrgOwnerID.HasValue && mp.AHSOrganization.Name.ToLower().Contains(keyword))))
                               orderby mp.Name
                               select mp).Distinct();
                }
                else if ((keyword != null) && (prjtype == 0))
                {
                    //Select the project by name, use is owner by name, organization is owner by name  
                    projects = (from mp in this.mdb.AHSMainProjects
                               where (mp.Name.ToLower().Contains(keyword) || mp.Description.ToLower().Contains(keyword) || 
                                    (mp.OwnerID.HasValue && mp.AHSAspnetMembership.AHSAspnetUser.Username.ToLower().Contains(keyword)) || 
                                    (mp.OrgOwnerID.HasValue && mp.AHSOrganization.Name.ToLower().Contains(keyword)))
                               orderby mp.Name
                               select mp).Distinct();
                }
                else if ((keyword == null) && (prjtype != 0))
                {
                    //Select the project by projecttype
                    projects = (from mp in this.mdb.AHSMainProjects
                               where (mp.ProjectTypeID == prjtype) && (mp.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                               orderby mp.Name
                               select mp).Distinct();
                }
                else
                {
                    //Select the project 
                    projects = (from mp in this.mdb.AHSMainProjects 
                               where (mp.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                               orderby mp.Name
                               select mp).Distinct();
                }

                if (projects == null)
                {
                    return null;
                }

                foreach (var item in projects)
                {
                    var user_name = item.OwnerID != null ? item.AHSAspnetMembership.AHSAspnetUser.Username : "";
                    var org_name = item.OrgOwnerID != null ? item.AHSOrganization.Name : "";

                    ret.Add(new Project(item.Id, item.Name, item.Description, item.DateCreated, item.EndDate, item.Owner,
                        item.OwnerIsUser, item.OwnerID, user_name,
                        item.OrgOwnerID, org_name, item.ProjectTypeID, item.AHSProjectType.Name, item.AHSProjectType.IsPM, item.RoleTypeID,
                        item.AHSProjectType.PathIcon, item.AHSProjectType.ApplicationURL));
                }

                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] SearchListBySA error {0}", ex);
                return null;
            }
        }

        /// <summary>
        /// Author:Le Ngoc Thach
        /// Modify: Hoang Van Tai
        /// </summary>
        /// <param name="email"></param>
        /// <param name="Projectid"></param>
        /// <returns></returns>
        public AHSInviteEmail InviteUserToProjectByEmail(Guid? code, string email, int projectid, Guid? ownerid, Guid? roleid)
        {
            try
            {
                AHSInviteEmail invite = null;

                // If code = null then add InviteEmail
                if (code == null)
                {
                    invite = new AHSInviteEmail();
                    invite.Code = Guid.NewGuid();
                    invite.OwnerID = ownerid;
                    invite.Email = email;
                    invite.PrjID = projectid;

                    if ((roleid != null) && (roleid.ToString() != "00000000-0000-0000-0000-000000000000"))
                    {
                        invite.RoleID = roleid;
                    }
                    else
                    {
                        invite.RoleID = null;
                    }

                    this.mdb.AHSInviteEmails.InsertOnSubmit(invite);
                }
                else
                {
                    invite = (from iv in this.mdb.AHSInviteEmails
                                  where iv.Code == code.Value
                                  select iv).FirstOrDefault();

                    if (invite == null)
                    {
                        invite = new AHSInviteEmail();
                        invite.Code = Guid.NewGuid();
                        invite.OwnerID = ownerid;
                        invite.Email = email;
                        invite.PrjID = projectid;

                        if ((roleid != null) && (roleid.ToString() != "00000000-0000-0000-0000-000000000000"))
                        {
                            invite.RoleID = roleid;
                        }
                        else
                        {
                            invite.RoleID = null;
                        }
                        this.mdb.AHSInviteEmails.InsertOnSubmit(invite);
                    }
                    else
                    { // Update 
                        invite.Email = email;
                        invite.PrjID = projectid;

                        if ((roleid != null) && (roleid.ToString() != "00000000-0000-0000-0000-000000000000"))
                        {
                            invite.RoleID = roleid;
                        }
                        else
                        {
                            invite.RoleID = null;
                        }
                    }
                }
                this.mdb.SubmitChanges();
                return invite;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.InviteUserToProjectByEmail error {0}", ex);
                return null; 
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// </summary>
        /// <param name="user"></param>
        /// <param name="name"></param>
        /// <param name="description"></param>
        /// <param name="datecreated"></param>
        /// <param name="status"></param>
        /// <param name="prjtype"></param>
        /// <param name="roltype"></param>
        /// <param name="ownerid"></param>
        /// <param name="ownerisuser"></param>
        /// <param name="idUserRoles"></param>
        /// <param name="idOrgRoles"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public int AddMainProject(string user, string name, string description, DateTime datecreated, DateTime? enddate, int status, int prjtype, int roltype, Guid ownerid, int ownerisuser, string[] idUserRoles, string[] idOrgRoles, ref string message)
        {
            try
            {
                var query = (from us in this.mdb.AHSAspnetUsers
                             where (us.Username.ToLower() == user.ToLower())
                             select us).FirstOrDefault();

                Guid userinviteId = query.Userid;

                if (string.IsNullOrWhiteSpace(name))
                {
                    message = "Main project name is empty";
                    return -1;
                }

                AHSDbContext.AHSMainProject mainproject = new AHSMainProject();
                mainproject.Name = name.Trim();
                mainproject.Description = description;
                mainproject.DateCreated = datecreated;
                mainproject.EndDate = enddate;
                mainproject.Status = status;
                mainproject.Owner = user;

                mainproject.ProjectTypeID = prjtype;
                mainproject.RoleTypeID = roltype;
                mainproject.OwnerIsUser = (ownerisuser == 1);

                if (mainproject.OwnerIsUser.Value)
                {
                    //owner is user
                    if (ownerid.ToString() != "00000000-0000-0000-0000-000000000000")
                    {
                        mainproject.OwnerID = ownerid;
                    }
                    else
                    {
                        mainproject.OwnerID = null;
                    }
                    mainproject.OrgOwnerID = null;
                }
                else
                {
                    //owner is org
                    mainproject.OwnerID = null;
                    mainproject.OrgOwnerID = ownerid;
                }

                this.mdb.AHSMainProjects.InsertOnSubmit(mainproject);
                this.mdb.SubmitChanges();

                //Add Known: Hiện tại chưa có phần Known trong CS
                //if (mainproject.OwnerIsUser.Value)
                //{
                //    //owner is user
                //    if (mainproject.OwnerID != null) AddKnown(mainproject.OwnerID.Value, mainproject.Id);
                //}
                //AddKnown(Guid.Parse(cu.ProviderUserKey.ToString()), mainproject.Id);

                AHSDbContext.AHSMainProject newMainPrj = _GetMainProjectByName(mainproject.Name);

                //Add UsersInProject
                if (newMainPrj != null && idUserRoles != null)
                {
                    UserManager um = new UserManager(this.ApplicationName);
                    um.AddUsersToProject(newMainPrj.Id, userinviteId, ref message, idUserRoles);
                }

                //Add OrgInProject
                if (newMainPrj != null && idOrgRoles != null)
                {
                    OrganizationManager om = new OrganizationManager(this.ApplicationName);
                    om.AddOrgsToProject(newMainPrj.Id, idOrgRoles, ref message);
                }

                return mainproject.Id;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.AddMainProject error {0}", ex);

                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// </summary>
        /// <param name="user"></param>
        /// <param name="mainPrjId"></param>
        /// <param name="name"></param>
        /// <param name="description"></param>
        /// <param name="prjtype"></param>
        /// <param name="roltype"></param>
        /// <param name="ownerid"></param>
        /// <param name="ownerisuser"></param>
        /// <param name="idUserRoles"></param>
        /// <param name="idOrgRoles"></param>
        /// <param name="idUserDels"></param>
        /// <param name="idOrgDels"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public int UpdateMainProject(string user, int mainPrjId, string name, string description, int prjtype, int roltype, Guid ownerid, int ownerisuser, string[] idUserRoles, string[] idOrgRoles, string[] idUserDels, string[] idOrgDels, ref string message)
        {
            try
            {
                AHSMainProject mainproject = (from mp in this.mdb.AHSMainProjects where mp.Id == mainPrjId select mp).FirstOrDefault();

                var query = (from us in this.mdb.AHSAspnetUsers
                            where (us.Username.ToLower() ==user.ToLower())
                            select us).FirstOrDefault();

                Guid userinviteId = query.Userid;

                if (mainproject == null)
                {
                    message = "Main project not exist";
                    return -1;
                }

                mainproject.Name = name.Trim();
                mainproject.Description = description == null ? "" : description;

                mainproject.ProjectTypeID = prjtype;
                mainproject.RoleTypeID = roltype;
                mainproject.OwnerIsUser = (ownerisuser == 1);
                if (mainproject.OwnerIsUser.Value)
                {
                    //owner is user
                    if (ownerid.ToString() != "00000000-0000-0000-0000-000000000000")
                    {
                        mainproject.OwnerID = ownerid;
                    }
                    else
                    {
                        mainproject.OwnerID = null;
                    }
                    mainproject.OrgOwnerID = null;
                }
                else
                {
                    //owner is org
                    mainproject.OwnerID = null;
                    mainproject.OrgOwnerID = ownerid;
                }

                this.mdb.SubmitChanges();

                //Add Known: Hiện chưa có phần Known trong CS
                //if (mainproject.OwnerIsUser.Value)
                //{
                //    //owner is user
                //    if (mainproject.OwnerID != null) AddKnown(mainproject.OwnerID.Value, mainproject.Id);
                //}
                //AddKnown(Guid.Parse(cu.ProviderUserKey.ToString()), mainproject.Id);

                //Update UsersInProject
                UserManager um = new UserManager(this.ApplicationName);  
                if (idUserDels != null)
                {
                    um.RemoveUsersFromProject(idUserDels, mainPrjId);
                }

                if (idUserRoles != null) um.AddUsersToProject(mainPrjId, userinviteId, ref message, idUserRoles);

                //Update OrgInProject
                OrganizationManager om = new OrganizationManager(this.ApplicationName);

                if (idOrgDels != null)
                {
                    om.RemoveOrgsFromProject(idOrgDels, mainPrjId);
                }

                if (idOrgRoles != null) om.AddOrgsToProject(mainPrjId, idOrgRoles, ref message);

                return mainproject.Id;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.UpdateMainProject error {0}", ex);
                message = ex.Message;

                return -1;
            }
        }

        /// <summary>
        /// Author:Hoang Van Tai
        /// </summary>
        /// <param name="mainPrjId"></param>
        /// <param name="idUserRoles"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public int SaveInviteUsersToProject(int mainPrjId, string userinviteId, string[] idUserRoles, ref string message)
        {
            try
            {
                ApplicationLinkManager alm = new ApplicationLinkManager(this.ApplicationName);
                string root = alm.GetLinkByApplication(); 

                Guid _RoleId;

                foreach (var idUserRole in idUserRoles)
                {
                    string[] arrUserRole = idUserRole.Split('^');

                    // Invite User to this project: AddItem
                    if (arrUserRole[4] == "0")
                    {
                        //arrUserRole[0] is email => Check email exist in memberships. if not exist then send email invitation

                        var email = arrUserRole[2];
                        _RoleId = Guid.Parse(arrUserRole[3]);

                        var ret = InviteUserToProjectByEmail(null, email, mainPrjId, Guid.Parse(userinviteId), _RoleId);

                        var activeLink = String.Format(@" <a href='" + root + "Account/Register?codes=" + ret.Code + "'>here</a> ");
                        var cs4 = String.Format(@" <a href='" + root + "'>Collaboration System</a>");
                        string body = String.Format(@"Click" + activeLink + "to register your account to " + cs4);

                        NotificationUtils.SendMail("CS Admin", email, "Invite", body, MailType.ExternalNotification);

                    }
                    else
                    { // Update
                        var inviteEmail = (from ivt in this.mdb.AHSInviteEmails
                                           where ivt.Code == Guid.Parse(arrUserRole[0])
                                           select ivt).FirstOrDefault();

                        if (inviteEmail != null)
                        {
                            if ((arrUserRole[3] != "null") && (arrUserRole[3] != "00000000-0000-0000-0000-000000000000"))
                            {
                                inviteEmail.RoleID = Guid.Parse(arrUserRole[3]);
                            }
                            else
                            {
                                inviteEmail.RoleID = null;
                            }

                        }
                        else
                        { // Không thấy tự thêm mới

                            var query = (from uprj in this.mdb.AHSUserInProjects
                                         where ((uprj.Userid == Guid.Parse(arrUserRole[0])) && (uprj.Projectid == mainPrjId)) &&
                                                 (uprj.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                         select uprj).FirstOrDefault();

                            if (query != null)
                            {
                                if ((arrUserRole[3] != "null") && (arrUserRole[3] != "00000000-0000-0000-0000-000000000000"))
                                {
                                    query.Roleid = Guid.Parse(arrUserRole[3]);
                                }
                                else
                                {
                                    query.Roleid = null;
                                }
                            }
                        }
                    }
                }

                this.mdb.SubmitChanges();

                return mainPrjId;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.SaveInviteUsersToProject error {0}", ex);

                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// </summary>
        /// <param name="mainPrjId"></param>
        /// <param name="userinviteId"></param>
        /// <param name="root"></param>
        /// <param name="idUserRoles"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public int SaveUsersToProject(int mainPrjId, string userinviteId, string[] idUserRoles, ref string message)
        {
            try
            {
                if (idUserRoles != null)
                {
                    UserManager um = new UserManager(this.ApplicationName);

                    um.AddUsersToProject(mainPrjId, Guid.Parse(userinviteId), ref message, idUserRoles);
                }
                
                return mainPrjId;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.SaveUsersToProject error {0}", ex);

                message = ex.Message;
                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// </summary>
        /// <param name="idPrj"></param>
        /// <param name="message"></param>
        /// <param name="idOrgRoles"></param>
        /// <returns></returns>
        public int SaveOrganizationdRoleFromPrj(int idPrj, string[] idOrgRoles, ref string message)
        {
            try
            {
                string _message = String.Empty;

                foreach (var idOrgRole in idOrgRoles)
                {
                    string[] arrOrgRole = idOrgRole.Split('^');

                    var query = (from org in this.mdb.AHSOrganizationInProjects
                                 where ((org.Projectid == idPrj) && (org.Orgid == Guid.Parse(arrOrgRole[0]))) && 
                                        (org.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                 select org).FirstOrDefault();

                    if (query != null)
                    {
                        if (arrOrgRole[1] != "00000000-0000-0000-0000-000000000000")
                        {
                            query.Roleid = Guid.Parse(arrOrgRole[1]);
                        }
                        else
                        {
                            query.Roleid = null;
                        }
                    }
                }

                this.mdb.SubmitChanges();
                
                return 0;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.SaveOrganizationdRoleFromPrj error {0}", ex);

                message = ex.Message;
                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// </summary>
        /// <param name="mainPrjId"></param>
        /// <returns></returns>
        public List<UserInProject> GetUserListFromProject(int mainPrjId)
        {
            try
            {
                List<UserInProject> ret = new List<UserInProject>();

                // Assign
                var list = from mp in this.mdb.AHSMainProjects
                           join uip in this.mdb.AHSUserInProjects on mp.Id equals uip.Projectid
                           orderby uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username
                           where (mp.Id == mainPrjId) && 
                                (mp.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                           select new { UserId = uip.Userid, UserName = uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username, ProjectId = uip.Projectid, ProjectName = mp.Name, RoleId = uip.Roleid, RoleName = uip.AHSAspnetRole.Rolename, type = uip.IsInvite, TT = uip.Status};

                foreach (var item in list)
                {
                    
                    var type = 0;

                    if (item.type != null)
                    {
                        type = item.type.Value ? 1 : 0;  // assign:0; Invite:1
                    }

                    // Invite
                    if (item.TT != null)
                    {
                        switch (item.TT)
                        {
                            case -1:
                                {
                                    type = -1;

                                    break;
                                }
                            case 0:
                                {
                                    // Reject
                                    type = 10;
                                    break;
                                }
                            case 1:
                                {
                                    // Accept
                                    type = 11;
                                    break;
                                }
                        }
                    }

                    ret.Add(new UserInProject(item.UserId, item.ProjectId, item.UserName, item.ProjectName, item.RoleId, item.RoleName, type));
                }

                // Invite 
                var query = (from ivt in this.mdb.AHSInviteEmails
                            where (ivt.PrjID == mainPrjId)
                            select new { UserId = ivt.Code, ProjectId = ivt.PrjID, username = ivt.Email, roleId = ivt.RoleID }).Distinct();

                foreach (var item in query)
                {
                    ret.Add(new UserInProject(item.UserId, item.ProjectId.Value, item.username, item.roleId, 1));
                }

                return ret;
            }
            catch (System.Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetUserListFromProject error {0}", ex);
                
                return null;
            }
        }

        /// <summary>
        /// Get Org List From Project
        /// </summary>
        /// <param name="mainPrjId"></param>
        /// <returns></returns>
        public List<OrgInProject> GetOrgListFromProject(int mainPrjId)
        {
            try
            {
                List<OrgInProject> ret = new List<OrgInProject>();

                var list = (from oip in this.mdb.AHSOrganizationInProjects
                           join mp in this.mdb.AHSMainProjects on oip.Projectid equals mp.Id
                           join org in this.mdb.AHSOrganizations on oip.Orgid equals org.Id
                           where (oip.Projectid == mainPrjId) &&
                                  (mp.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                           orderby org.Name
                           select new { OrgId = oip.Orgid, OrgName = org.Name, ProjectId = oip.Projectid, ProjectName = mp.Name, RoleId = oip.Roleid, IsInvite = oip.IsInvite, Status = oip.Status }).Distinct();

                foreach (var item in list)
                {
                    var _status = item.Status != null ? item.Status.Value : -1;

                    // Assign
                    if (!item.IsInvite.HasValue)
                    {
                        _status = 10;
                    }

                    ret.Add(new OrgInProject(item.OrgId, item.OrgName, item.ProjectId, item.ProjectName, item.RoleId, _status));
                }

                return ret;
            }
            catch (System.Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetOrgListFromProject error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public List<Project> GetMainProjectListFromUser(string username)
        {
            try
            {
                
                List<Project> ret = new List<Project>();

                var list = (from mp in this.mdb.AHSMainProjects
                            where (mp.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                            orderby mp.Name
                            select mp).Distinct();

                //PermissionManager pm = new PermissionManager(this.ApplicationName);
                foreach (var item in list)
                {
                    //if (pm.IsMainProjectAccessibleByUser(username, item.Id))
                    var user_name = item.OwnerID != null ? item.AHSAspnetMembership.AHSAspnetUser.Username : "";
                    var org_name = item.OrgOwnerID != null ? item.AHSOrganization.Name : "";
                    var name = item.Name;

                    ret.Add(new Project(item.Id, item.Name, item.Description, item.DateCreated, item.EndDate,
                            item.Owner, item.OwnerIsUser, item.OwnerID, user_name,
                            item.OrgOwnerID, org_name, item.ProjectTypeID, item.AHSProjectType.Name, item.AHSProjectType.IsPM, item.RoleTypeID, item.AHSProjectType.PathIcon, item.AHSProjectType.ApplicationURL));
                }
                return ret;
            }
            catch (System.Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] ProjectManager.GetMainProjectListFromUser error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Search Main Project list
        /// </summary>
        /// <param name="projectname"></param>
        /// <param name="orgId"></param>
        /// <param name="username"></param>
        /// <returns></returns>
        public List<Project> SearchMainProjectList(string projectname, string orgId, string username)
        {
            try
            {
                List<Project> ret = new List<Project>();
                IEnumerable<AHSMainProject> projects = null;

                if (string.IsNullOrEmpty(orgId))
                {
                    projects = (from mp in this.mdb.AHSMainProjects
                                join oip in this.mdb.AHSOrganizationInProjects on mp.Id equals oip.Projectid
                                join uip in this.mdb.AHSUserInProjects on mp.Id equals uip.Projectid
                                 where (mp.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower() &&
                                        mp.Name.Contains(projectname) &&
                                        uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username.Contains(username) )   
                                orderby mp.Name
                                select mp).Distinct();
                } else if (!string.IsNullOrEmpty(orgId))
                {
                    projects = (from mp in this.mdb.AHSMainProjects
                                join oip in this.mdb.AHSOrganizationInProjects on mp.Id equals oip.Projectid
                                join uip in this.mdb.AHSUserInProjects on mp.Id equals uip.Projectid
                                where (mp.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower() &&
                                       mp.Name.Contains(projectname) && oip.Orgid == Guid.Parse(orgId) &&
                                       uip.AHSAspnetMembership_Userid.AHSAspnetUser.Username.Contains(username))
                                orderby mp.Name
                                select mp).Distinct();

                }

                if (projects != null) 
                {

                    foreach (var item in projects)
                    {
                        var user_name = item.OwnerID != null ? item.AHSAspnetMembership.AHSAspnetUser.Username : "";
                        var org_name = item.OrgOwnerID != null ? item.AHSOrganization.Name : "";

                        ret.Add(new Project(item.Id, item.Name, item.Description, item.DateCreated, item.EndDate, item.Owner,
                            item.OwnerIsUser, item.OwnerID, user_name,
                            item.OrgOwnerID, org_name, item.ProjectTypeID, item.AHSProjectType.Name, item.AHSProjectType.IsPM, item.RoleTypeID,
                            item.AHSProjectType.PathIcon, item.AHSProjectType.ApplicationURL));
                    }
                }

                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] SearchMainProjectList error {0}", ex);
                return null;
            }
        }
    }
}